home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / Memory / ObjectHe.h < prev    next >
Encoding:
Text File  |  1996-08-28  |  13.3 KB  |  443 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        ObjectHe.h
  3.  
  4.     Contains:    ObjectHeap class interface
  5.  
  6.     Written by:    Michael Burbidge
  7.  
  8.     Copyright:    © 1993 - 1994 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.     
  12.          <4>     8/17/94    jpa        Added warning about incompatibility.
  13.          <3>      8/8/94    jpa        OD_DEBUG --> ODDebug
  14.          <2>     6/10/94    MB        Make it build
  15.          <1>      6/9/94    MB        first checked in
  16.          <2>      5/9/94    MB        #1162181: Changes necessary to install MMM.
  17.          <1>     4/29/94    MB        first checked in
  18.     To Do:
  19. */
  20.  
  21. $$$$$ This class is not being used as of 8/11/94. It is not quite up to date with
  22.       the changes I am making to the block headers in BestFitH; if we want to use
  23.       this class again we'll need to update PrivChunkyBlock to make it compatible
  24.       with PrivBestFitBlock.  --jpa
  25.  
  26.  
  27. #ifndef _OBJECTHE_
  28. #define _OBJECTHE_
  29.  
  30. #ifndef _PLATFMEM_
  31. #include "PlatfMem.h"
  32. #endif
  33.  
  34. #ifndef _MEMORYHE_
  35. #include "MemoryHe.h"
  36. #endif
  37.  
  38. #ifndef _BESTFITH_
  39. #include "BestFitH.h"
  40. #endif
  41.  
  42.  
  43. //========================================================================================
  44. // Forward class declarations
  45. //========================================================================================
  46.  
  47. class PrivChunk;
  48. class PrivChunkyBlock;
  49. class PrivChunkyBlockStack;
  50.  
  51.  
  52. //========================================================================================
  53. // CLASS PrivChunkyBlock
  54. //========================================================================================
  55.  
  56. #ifdef BUILD_WIN
  57. // Bytes are in reverse order in a word.
  58.  
  59. const unsigned short ChunkyBlock_kSizeIndexMask = 0x00F0;
  60. const unsigned short ChunkyBlock_kSizeIndexShift = 4;
  61.  
  62. const unsigned short ChunkyBlock_kBlockIndexMask = 0x000F;
  63. const unsigned short ChunkyBlock_kBlockIndexShift = 0;
  64.  
  65. const unsigned short ChunkyBlock_kBlockTypeMask = 0xF000;
  66. const unsigned short ChunkyBlock_kBlockTypeShift = 12;
  67.  
  68. const unsigned short ChunkyBlock_kMagicNumberMask = 0x0F00;
  69. const unsigned short ChunkyBlock_kMagicNumberShift = 8;
  70. #else
  71. const unsigned short ChunkyBlock_kSizeIndexMask = 0xF000;
  72. const unsigned short ChunkyBlock_kSizeIndexShift = 12;
  73.  
  74. const unsigned short ChunkyBlock_kBlockIndexMask = 0x0F00;
  75. const unsigned short ChunkyBlock_kBlockIndexShift = 8;
  76.  
  77. const unsigned short ChunkyBlock_kBlockTypeMask = 0x00F0;
  78. const unsigned short ChunkyBlock_kBlockTypeShift = 4;
  79.  
  80. const unsigned short ChunkyBlock_kMagicNumberMask = 0x000F;
  81. const unsigned short ChunkyBlock_kMagicNumberShift = 0;
  82. #endif
  83.  
  84. class PrivChunkyBlock
  85. {
  86. public:
  87.     enum
  88.     {
  89.         kBusyOverhead = sizeof(unsigned short), 
  90.         kBlockTypeId = PrivBestFitBlock::kBlockTypeId + 1, 
  91.         kMagicNumber = 0xA
  92.     };
  93.  
  94.     void *operator new(SIZE_T, void *ptr);
  95.     void *operator new(SIZE_T);
  96.     void operator delete(void *) { };
  97.  
  98.     PrivChunkyBlock();
  99.     PrivChunkyBlock(unsigned int sizeIndex, unsigned int blockIndex);
  100.     PrivChunkyBlock(const PrivChunkyBlock& blk);
  101.     PrivChunkyBlock& operator=(const PrivChunkyBlock& blk);
  102.     
  103.     unsigned short GetSizeIndex() const;
  104.     void SetSizeIndex(unsigned short index);
  105.     
  106.     unsigned short GetBlockIndex() const;
  107.     void SetBlockIndex(unsigned short index);
  108.     
  109.     unsigned short GetBlockType() const;
  110.     void SetBlockType(unsigned short type);
  111.     
  112.     unsigned short GetMagicNumber() const;
  113.     void SetMagicNumber(unsigned short magic);    
  114.  
  115.     PrivChunk* GetChunk(ODBlockSize blkSize);
  116.     
  117.     PrivChunkyBlock* GetNext();
  118.     void SetNext(PrivChunkyBlock* blk);
  119.  
  120.     Boolean IsBusy(ODBlockSize blockSize);
  121.     void SetBusy(ODBlockSize blockSize, Boolean busy);
  122.  
  123. private:
  124.     // Fields present in both free and busy blocks. Several bit fields are stored in
  125.     // the following fields. They are accessed using get and set methods.
  126.  
  127.     unsigned short fBits;
  128.  
  129.     // Fields present in only free blocks.
  130.  
  131.     PrivChunkyBlock* fNext;
  132. };
  133.  
  134.  
  135. //========================================================================================
  136. // CLASS PrivChunkyBlockStack
  137. //========================================================================================
  138.  
  139. class PrivChunkyBlockStack
  140. {
  141. public:
  142.     PrivChunkyBlockStack();
  143.     PrivChunkyBlockStack(const PrivChunkyBlockStack& blk);
  144.     ~PrivChunkyBlockStack();
  145.     PrivChunkyBlockStack& operator=(const PrivChunkyBlockStack& blk);
  146.     
  147.     void *operator new(size_t size);
  148.     void operator delete(void *);
  149.  
  150.     PrivChunkyBlock* Pop();
  151.     void Push(PrivChunkyBlock* blk);
  152.     void RemoveRange(void *begAddr, void *endAddr);
  153.     PrivChunkyBlock* Top();
  154.  
  155. private:
  156.     PrivChunkyBlock fHead;
  157. };
  158.  
  159.  
  160. //========================================================================================
  161. // CLASS PrivChunk
  162. //========================================================================================
  163.  
  164. struct ODPrivChunkHeader
  165. {
  166.     unsigned short fBlockBusyBits;
  167. };
  168.  
  169. class PrivChunk
  170. {
  171. public:
  172.     PrivChunk(short blocksPerChunk,
  173.               unsigned int sizeIndex,
  174.               ODBlockSize blockSize);
  175.  
  176.     void *operator new(SIZE_T, void* ptr);
  177.     void *operator new(SIZE_T);
  178.     void operator delete(void *) { };
  179.  
  180.     PrivChunkyBlock* GetBlock(unsigned int blkIndex, ODBlockSize blkSize);
  181.     unsigned int GetSizeIndex();
  182.  
  183.     Boolean IsBlockBusy(unsigned int whichBlock);
  184.     Boolean IsBusy();
  185.  
  186.     void SetBlockBusy(unsigned int whichBlock, Boolean busy);
  187.  
  188. private:
  189.     ODPrivChunkHeader fHeader;
  190.     
  191.     PrivChunk(const PrivChunk& blk);
  192.     PrivChunk& operator=(const PrivChunk& blk);
  193.         // This class shouldn't be copied.
  194. };
  195.  
  196.  
  197. //========================================================================================
  198. // CLASS ObjectHeap
  199. //========================================================================================
  200.  
  201. extern const ODBlockSize ObjectHeap_kDefaultBlockSizes[];
  202.  
  203. class ObjectHeap : public BestFitHeap
  204. {
  205. private:
  206.  
  207. public:
  208.     enum
  209.     {
  210.         kMaxNumberOfBlockSizes = 16,
  211.         kDefaultBlocksPerChunk = 4,
  212.         kDefaultInitialSize = 10240,
  213.         kDefaultIncrementSize = 4096
  214.     };
  215.  
  216.     ObjectHeap(unsigned long initialSize,
  217.              unsigned long incrementSize = 0,
  218.              unsigned long hugeBlockSize = 0,        // 0 means incrementSize/2
  219.              Boolean fromSysMemory = false,
  220.              short blocksPerChunk = kDefaultBlocksPerChunk);
  221.  
  222.     ObjectHeap(const ODBlockSize* blockSizes,
  223.              unsigned long initialSize = kDefaultInitialSize,
  224.              unsigned long incrementSize = kDefaultIncrementSize,
  225.              unsigned long hugeBlockSize = 0,        // 0 means incrementSize/2
  226.              Boolean fromSysMemory = false,
  227.              short blocksPerChunk = kDefaultBlocksPerChunk);
  228.  
  229.     void IObjectHeap();
  230.  
  231.     virtual ~ObjectHeap();
  232.  
  233. protected:
  234.     virtual void* DoAllocate(ODBlockSize size, ODBlockSize& allocatedSize);
  235.     virtual ODBlockSize DoBlockSize(const void* block) const;
  236.     virtual void DoFree(void*);
  237.     virtual void DoReset();
  238.  
  239.     void* AllocateBlock(unsigned int sizeIndex);
  240.     void CreateNewChunk(unsigned int sizeIndex);
  241.     void FreeBlock(PrivChunkyBlock* blk);
  242.     unsigned int SizeIndex(ODBlockSize size);
  243.  
  244. #if ODDebug
  245.     virtual void CompilerCheck();
  246.     virtual Boolean DoIsValidBlock(void* blk) const;
  247. #endif
  248.  
  249. private:
  250.     
  251.     short fNumberOfBlockSizes;
  252.     const ODBlockSize* fBlockSizes;
  253.     PrivChunkyBlockStack fFreeLists[kMaxNumberOfBlockSizes];
  254.     short fBlocksPerChunk;
  255.     
  256.     ObjectHeap(const ObjectHeap& blk);
  257.     ObjectHeap& operator=(const ObjectHeap& blk);
  258.         // This class shouldn't be copied.
  259. };
  260.  
  261.  
  262. //========================================================================================
  263. // CLASS PrivChunkyBlock
  264. //========================================================================================
  265.  
  266. //----------------------------------------------------------------------------------------
  267. // PrivChunkyBlock::operator new
  268. //----------------------------------------------------------------------------------------
  269.  
  270. inline void *PrivChunkyBlock::operator new(SIZE_T, void *ptr)
  271. {
  272.     return ptr;
  273. }
  274.  
  275. //----------------------------------------------------------------------------------------
  276. // PrivChunkyBlock::operator new
  277. //----------------------------------------------------------------------------------------
  278.  
  279. inline void *PrivChunkyBlock::operator new(SIZE_T)
  280. {
  281.     return NULL;
  282. }
  283.  
  284. //----------------------------------------------------------------------------------------
  285. // PrivChunkyBlock::PrivChunkyBlock
  286. //----------------------------------------------------------------------------------------
  287.  
  288. inline PrivChunkyBlock::PrivChunkyBlock(const PrivChunkyBlock& blk) :
  289.     fBits(blk.fBits),
  290.     fNext(blk.fNext)
  291. {
  292. }
  293.  
  294. //----------------------------------------------------------------------------------------
  295. // PrivChunkyBlock::operator=
  296. //----------------------------------------------------------------------------------------
  297.  
  298. inline PrivChunkyBlock& PrivChunkyBlock::operator=(const PrivChunkyBlock& blk)
  299. {
  300.     fBits = blk.fBits;
  301.     fNext = blk.fNext;
  302.     return *this;
  303. }
  304.  
  305. //----------------------------------------------------------------------------------------
  306. // PrivChunkyBlock::GetSizeIndex
  307. //----------------------------------------------------------------------------------------
  308.  
  309. inline unsigned short PrivChunkyBlock::GetSizeIndex() const
  310. {
  311.     return (fBits & ChunkyBlock_kSizeIndexMask) >> ChunkyBlock_kSizeIndexShift;
  312. }
  313.  
  314. //----------------------------------------------------------------------------------------
  315. // PrivChunkyBlock::SetSizeIndex
  316. //----------------------------------------------------------------------------------------
  317.  
  318. inline void PrivChunkyBlock::SetSizeIndex(unsigned short index)
  319. {
  320.     fBits &= ~ChunkyBlock_kSizeIndexMask;
  321.     fBits |= (index << ChunkyBlock_kSizeIndexShift) & ChunkyBlock_kSizeIndexMask;
  322. }
  323.     
  324. //----------------------------------------------------------------------------------------
  325. // PrivChunkyBlock::GetBlockIndex
  326. //----------------------------------------------------------------------------------------
  327.  
  328. inline unsigned short PrivChunkyBlock::GetBlockIndex() const
  329. {
  330.     return (fBits & ChunkyBlock_kBlockIndexMask) >> ChunkyBlock_kBlockIndexShift;
  331. }
  332.  
  333. //----------------------------------------------------------------------------------------
  334. // PrivChunkyBlock::SetBlockIndex
  335. //----------------------------------------------------------------------------------------
  336.  
  337. inline void PrivChunkyBlock::SetBlockIndex(unsigned short index)
  338. {
  339.     fBits &= ~ChunkyBlock_kBlockIndexMask;
  340.     fBits |= (index << ChunkyBlock_kBlockIndexShift) & ChunkyBlock_kBlockIndexMask;
  341. }
  342.     
  343. //----------------------------------------------------------------------------------------
  344. // PrivChunkyBlock::GetBlockType
  345. //----------------------------------------------------------------------------------------
  346.  
  347. inline unsigned short PrivChunkyBlock::GetBlockType() const
  348. {
  349.     return (fBits & ChunkyBlock_kBlockTypeMask) >> ChunkyBlock_kBlockTypeShift;
  350. }
  351.  
  352. //----------------------------------------------------------------------------------------
  353. // PrivChunkyBlock::SetBlockType
  354. //----------------------------------------------------------------------------------------
  355.  
  356. inline void PrivChunkyBlock::SetBlockType(unsigned short type)
  357. {
  358.     fBits &= ~ChunkyBlock_kBlockTypeMask;
  359.     fBits |= (type << ChunkyBlock_kBlockTypeShift) & ChunkyBlock_kBlockTypeMask;
  360. }
  361.     
  362. //----------------------------------------------------------------------------------------
  363. // PrivChunkyBlock::GetMagicNumber
  364. //----------------------------------------------------------------------------------------
  365.  
  366. inline unsigned short PrivChunkyBlock::GetMagicNumber() const
  367. {
  368.     return (fBits & ChunkyBlock_kMagicNumberMask) >> ChunkyBlock_kMagicNumberShift;
  369. }
  370.  
  371. //----------------------------------------------------------------------------------------
  372. // PrivChunkyBlock::SetMagicNumber
  373. //----------------------------------------------------------------------------------------
  374.  
  375. inline void PrivChunkyBlock::SetMagicNumber(unsigned short magic)
  376. {
  377.     fBits &= ~ChunkyBlock_kMagicNumberMask;
  378.     fBits |= (magic << ChunkyBlock_kMagicNumberShift) & ChunkyBlock_kMagicNumberMask;
  379. }    
  380.  
  381. //----------------------------------------------------------------------------------------
  382. // PrivChunkyBlock::GetNext
  383. //----------------------------------------------------------------------------------------
  384.  
  385. inline PrivChunkyBlock* PrivChunkyBlock::GetNext()
  386. {
  387.     return fNext;
  388. }
  389.  
  390. //----------------------------------------------------------------------------------------
  391. // PrivChunkyBlock::SetNext
  392. //----------------------------------------------------------------------------------------
  393.  
  394. inline void PrivChunkyBlock::SetNext(PrivChunkyBlock* blk)
  395. {
  396.     fNext = blk;
  397. }
  398.  
  399.  
  400. //========================================================================================
  401. // CLASS PrivChunk
  402. //========================================================================================
  403.  
  404. //----------------------------------------------------------------------------------------
  405. // PrivChunk::operator new
  406. //----------------------------------------------------------------------------------------
  407.  
  408. inline void* PrivChunk::operator new(SIZE_T, void *ptr)
  409. {
  410.     return ptr;
  411. }
  412.  
  413. //----------------------------------------------------------------------------------------
  414. // PrivChunk::operator new
  415. //----------------------------------------------------------------------------------------
  416.  
  417. inline void* PrivChunk::operator new(SIZE_T)
  418. {
  419.     return NULL;
  420. }
  421.  
  422. //----------------------------------------------------------------------------------------
  423. // PrivChunk::GetSizeIndex
  424. //----------------------------------------------------------------------------------------
  425.  
  426. inline unsigned int PrivChunk::GetSizeIndex()
  427. {
  428.     PrivChunkyBlock *block 
  429.         = (PrivChunkyBlock *) ((ODBytePtr) this + sizeof(ODPrivChunkHeader));
  430.     return block->GetSizeIndex();
  431. }
  432.  
  433. //----------------------------------------------------------------------------------------
  434. // PrivChunk::IsBusy
  435. //----------------------------------------------------------------------------------------
  436.  
  437. inline Boolean PrivChunk::IsBusy()
  438. {
  439.     return fHeader.fBlockBusyBits != 0;
  440. }
  441.  
  442. #endif
  443.